﻿using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;


namespace LL2024.Models.CommonLibraries.Services
{
    public class NetTimeService
    {
        #region 获取互联网时间
        private static readonly ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random());

        private static string GetRandomServer()
        {
#pragma warning disable CS8602 // 解引用可能出现空引用。
            int index = random.Value.Next(Servers.Length);
#pragma warning restore CS8602 // 解引用可能出现空引用。
            return Servers[index];
        }
        private static string[] Servers = { "ntp.aliyun.com",
                                            "ntp1.aliyun.com",
                                            "ntp2.aliyun.com",
                                            "ntp3.aliyun.com",
                                            "ntp4.aliyun.com",
                                            "ntp5.aliyun.com",
                                            "ntp6.aliyun.com",
                                            "ntp7.aliyun.com"
                                            };
        public static DateTime? GetAliYunTime()
        {
            try
            {
                string ntpServer = GetRandomServer();
                var ntpData = new byte[48];
                ntpData[0] = 0x1B;
                try
                {
                    var addresses = Dns.GetHostEntry(ntpServer).AddressList;
                    var ipEndPoint = new IPEndPoint(addresses[0], 123);
                    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    socket.Connect(ipEndPoint);
                    socket.ReceiveTimeout = 3000;
                    socket.Send(ntpData);
                    socket.Receive(ntpData);
                    socket.Close();
                }
                catch
                {
                    return null;
                }
                const byte serverReplyTime = 40;
                ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
                ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
                intPart = SwapEndianness(intPart);
                fractPart = SwapEndianness(fractPart);
                var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
                //计算后的时间
                var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
                var networkDateTimeCst = TimeZoneInfo.ConvertTimeFromUtc(networkDateTime, TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"));
                return networkDateTimeCst;

                uint SwapEndianness(ulong x)
                {
                    return (uint)(((x & 0x000000ff) << 24) +
                    ((x & 0x0000ff00) << 8) +
                    ((x & 0x00ff0000) >> 8) +
                    ((x & 0xff000000) >> 24));
                }
            }
            catch { return null; }
        }
        #endregion




        private static readonly HttpClient client = new HttpClient();

        public async Task<string> GetSunngInternetTime()
        {
            try
            {
                HttpResponseMessage response = await client.GetAsync("https://f.m.suning.com/api/ct.do");
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                SuningTime timenet2 = JsonSerializer.Deserialize<SuningTime>(responseBody);
                if (timenet2 != null && timenet2.currentTime.ToString().Length == 13)
                    return timenet2.currentTime.ToString();
            }
            catch
            {
            }
            return "";
        }

        public async Task<string> GetsapiTime()
        {
            try
            {
                HttpResponseMessage response = await client.GetAsync("https://sapi.k780.com/?app=time.world&city_en=beijing&appkey=75215&sign=c2db774345c3bfeb4bf64f504e3c96b8&format=json");
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                TimeInfoResponse timenet2 = JsonSerializer.Deserialize<TimeInfoResponse>(responseBody);
                if (timenet2 != null && timenet2.Result != null && timenet2.Result.bjt_timestamp != null)
                    return timenet2.Result.bjt_timestamp + "000";
            }
            catch
            {
            }
            return "";
        }

        /// <summary>  
        /// 时间戳Timestamp转换成日期  
        /// </summary>  
        /// <param name="timeStamp"></param>  
        /// <returns></returns>  
        public static DateTime ConvertUnixToDateTime(string timeStamp)
        {
            if (long.TryParse(timeStamp, out long longdata))
            {
                // 使用 TimeZoneInfo 获取本地时区信息
                TimeZoneInfo localZone = TimeZoneInfo.Local;
                // 创建一个 UTC 时间点（Unix 时间起点）
                DateTime unixEpochUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                // 将 UTC 时间转换为本地时间
                DateTime dtStart = TimeZoneInfo.ConvertTimeFromUtc(unixEpochUtc, localZone);
                //DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                long lTime = long.Parse(longdata + "0000");
                TimeSpan toNow = new TimeSpan(lTime);
                return dtStart.Add(toNow);
            }
            return DateTime.Now;
        }

        public async Task<DateTime> GetFastestInternetTime()
        {
            var data = GetAliYunTime();
            if (data is DateTime)
            {
                if (data.Value.Year > 2024)
                    return (DateTime)data;
            }

            // 创建所有请求任务
            var tasks = new[]
            {
            GetSunngInternetTime(), GetsapiTime(),
         };

            // 等待所有任务完成
            var results = await Task.WhenAll(tasks);

            // 查找第一个非空的结果
            var firstValidResult = results.FirstOrDefault(result => !string.IsNullOrEmpty(result));

            // 如果找到有效的结果，返回它；否则抛出异常
            if (!string.IsNullOrEmpty(firstValidResult))
            {
                return ConvertUnixToDateTime(firstValidResult);
            }
            else
            {
                throw new Exception("无法获取互联网时间，可能没有网络连接。");
            }
        }
    }
    #region 时间接口响应参数

    /// <summary>
    /// 苏宁
    /// </summary>
    public class SuningTime
    {
        /// <summary>
        /// 
        /// </summary>
        public string api { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string code { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public long currentTime { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string msg { get; set; }

    }



    public class TimeInfoResponse
    {
        public string Success { get; set; }

        public Result Result { get; set; }
    }

    public class Result
    {
        public string bjt_timestamp { get; set; } // 修改为字符串类型


    }
    #endregion
}
